#include"main_server.h"

// 如果有数据过来进入dns_queue队列，则读取数据，然后发给dns service
void new_dns_request(event_loop *loop, int fd, void *args){
    
    // 得到client
    tcp_client* client = (tcp_client*)args;

    // 1.将数据从dns_queue队列中取出
    std::queue<lars::GetRouteRequest> queue;

    // 2.将取出的数据放在一个queue队列中
    dns_queue->recv(queue);

    // 3.遍历容器中的元素，以此将每个元素消息发送给dns_service
    while(!queue.empty()){
        // 获取其中的每一个消息元素
        lars::GetRouteRequest msg = queue.front();
        queue.pop();

        // 将消息转换成字符串
        std::string requestString;
        msg.SerializeToString(&requestString);

        // 尝试将消息请求发给dns service
        client->send_message(requestString.c_str(), requestString.size(), lars::ID_GetRouteRequest);
    }
}

// 创建agent与dns service链接后的HOOK函数
void conn_init(net_connection *conn, void *args){
    // 让所有的udp server的route_lb下的所有load_balance都重置为NEW状态
    for(int i=0; i<config.udp_server_cnt; i++){
        r_lb[i]->reset_lb_status();
    }
}


// 处理收到dns service发来的数据
void deal_recv_route(const char *data, uint32_t len, int msgid, net_connection* net_conn, void *args){
    printf("recv from dns service message\n");
    // 解析数据
    lars::GetRouteResponse response;
    response.ParseFromArray(data, len);

    int modid = response.modid();
    int cmdid = response.cmdid();

    // 将当前modid/cmdid下的host信息，放入r_lb[index]下的load_balance中
    int index = (modid + cmdid) % 3;
    r_lb[index]->update_host(modid, cmdid, response);

}

// 启动dns客户端的回调函数
void* dns_client_thread(void* args){
    printf("dns client thread start\n");
    
    event_loop loop;
    
    // 设定一个tcp客户端与服务器连接
    tcp_client client(&loop, config.dns_ip.c_str(), config.dns_port);

    // 设定一个loop监控queue中的数据
    dns_queue->set_loop(&loop);

    // 设置读函数
    dns_queue->set_callback(new_dns_request, &client);

    // 设置一个dns client创建成功的HOOK函数
    client.set_conn_start(conn_init);

    // 注册一个回调函数，处理dns service返回的数据
    client.add_msg_router(lars::ID_GetRouteResponse, deal_recv_route);


    loop.event_process();

    return NULL;
}

// 启动report客户端的函数
void start_dns_client(void *args){
    
    // 开辟一个新线程
    pthread_t tid;
    int ret = pthread_create(&tid, NULL, dns_client_thread, NULL);
    if(ret == -1){
        fprintf(stderr, "new thread dns error\n");
        exit(1);
    }

    pthread_detach(tid);


}